package com.sunda.spmsoversea.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsoversea.dto.WerksAllStorageInvSearchDTO;
import com.sunda.spmsoversea.dto.WerksStorageInvSearchDTO;
import com.sunda.spmsoversea.dto.WhsStorageInvSearchDTO;
import com.sunda.spmsoversea.entity.WhsStorageInventory;
import com.sunda.spmsoversea.mapper.WhsStorageInventoryMapper;
import com.sunda.spmsoversea.service.IWhsStorageInventoryService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

import static com.sunda.spmsoversea.constant.WhsStorageInventoryConstant.ADD;
import static com.sunda.spmsoversea.constant.WhsStorageInventoryConstant.SUB;

/**
 * <p>
 * 储位库存信息表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-09-10
 */
@Service("overseaWhsStorageInventoryServiceImpl")
public class WhsStorageInventoryServiceImpl extends ServiceImpl<WhsStorageInventoryMapper, WhsStorageInventory> implements IWhsStorageInventoryService {

    /** 线程安全控制————海外仓储位库存操作，包括库存校验，operateType = add 加库存；operateType = sub 减库存；加减库存时 qty 都取正数；此法不带操作日志；*/
    @Override
    public synchronized ResponseResult updateWhsStorageInventory(String storageUuid, String materialNo, double qty, String operateType) {
        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(materialNo)) {
            return ResponseResult.error().add("error", "storageUuid 或 materialNo 不能为空");
        }
        if (qty <= 0) {
            return ResponseResult.error().add("error", "qty 不能小于等于0");
        }
        try {
            QueryWrapper<WhsStorageInventory> queryWrapper = new QueryWrapper<WhsStorageInventory>().eq("UUID", storageUuid).eq("MATERIAL_NO", materialNo);
            WhsStorageInventory storageInventory = this.baseMapper.selectOne(queryWrapper);
            if (ADD.equals(operateType)) {
                // 加储位库存——已存在更新；不存在则新增；
                if (null != storageInventory) {
                    double quantity = storageInventory.getQuantity() + qty;
                    double availableQty = storageInventory.getAvailableQty() + qty;
                    WhsStorageInventory inventory = new WhsStorageInventory();
                    inventory.setQuantity(quantity);
                    inventory.setAvailableQty(availableQty);
                    this.baseMapper.update(inventory, queryWrapper);
                } else {
                    WhsStorageInventory whsStorageInventory = new WhsStorageInventory();
                    whsStorageInventory.setUuid(storageUuid);
                    whsStorageInventory.setMaterialNo(materialNo);
                    whsStorageInventory.setQuantity(qty);
                    whsStorageInventory.setAvailableQty(qty);
                    this.baseMapper.insert(whsStorageInventory);
                }
                return ResponseResult.success();
            }
            if (SUB.equals(operateType)) {
                // 减储位库存，操作数大于库存则返回错误提示；操作数等于库存则删除该库存；操作数小于库存则更新该库存；
                if (null != storageInventory) {
                    if (qty > storageInventory.getAvailableQty()) {
                        return ResponseResult.error().add("error", materialNo + "在储位" + storageUuid + "库存不足，请检查重试");
                    }
                    if (qty == storageInventory.getAvailableQty()) {
                        this.baseMapper.delete(queryWrapper);
                        return ResponseResult.success();
                    }
                    if (qty < storageInventory.getAvailableQty()) {
                        storageInventory.setQuantity(storageInventory.getQuantity() - qty);
                        storageInventory.setAvailableQty(storageInventory.getAvailableQty() - qty);
                        this.baseMapper.update(storageInventory, queryWrapper);
                        return ResponseResult.success();
                    }
                } else {
                    return ResponseResult.error().add("error", materialNo + "在储位" + storageUuid + "不存在，请检查重试");
                }
            }
            return ResponseResult.error().add("error", "操作类型不正确");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: updateStorageInventoryM");
        }
    }

    @Override
    public WhsStorageInventory getWhsStorageInventory(String uuid, String materialNo) {
        if (StringUtils.isEmpty(uuid) || StringUtils.isEmpty(materialNo)){
            return null;
        }
        QueryWrapper<WhsStorageInventory> queryWrapper =
                new QueryWrapper<WhsStorageInventory>().eq("UUID", uuid).eq("MATERIAL_NO", materialNo);
        return this.baseMapper.selectOne(queryWrapper);
    }

    /** 本工厂 库存搜索：工厂、物料号、物料描述、库区、储位编号 —— 结果带具体储位信息，按储位给库存信息，工厂必输其余可选 */
    @Override
    public ResponseResult getWerksStorageInvList(WerksStorageInvSearchDTO werksStorageInvSearchDTO) {
        if (werksStorageInvSearchDTO == null || StringUtils.isEmpty(werksStorageInvSearchDTO.getWerks())){
            return ResponseResult.error("请求参数错误或查询工厂不能为空");
        }
        try {
            IPage iPage = werksStorageInvSearchDTO.getPage();
            List<Map<String, Object>> mapList = this.baseMapper.getWerksStorageInvList(iPage, werksStorageInvSearchDTO);
            return ResponseResult.success().add("whsStorageInvList", iPage.setRecords(mapList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksStorageInvList");
        }
    }

    /** 获取条件下所有储位库存，不分页 */
    @Override
    public ResponseResult getWerksAllStorageInv(WerksAllStorageInvSearchDTO werksAllStorageInvSearchDTO) {
        if (werksAllStorageInvSearchDTO == null || StringUtils.isEmpty(werksAllStorageInvSearchDTO.getWerks())){
            return ResponseResult.error("请求参数错误或查询工厂不能为空");
        }
        try {
            List<Map<String, Object>> mapList = this.baseMapper.getWerksAllStorageInv(werksAllStorageInvSearchDTO);
            return ResponseResult.success().add("whsStorageInvList", mapList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksAllStorageInv");
        }
    }

    /** 跨工厂 库存搜索：工厂、物料号、物料描述 —— 结果不带具体储位信息，按工厂物料求和，所有条件可选 */
    @Override
    public ResponseResult getStorageInvList(WhsStorageInvSearchDTO whsStorageInvSearchDTO) {
        if (whsStorageInvSearchDTO == null){
            return ResponseResult.error("请求参数错误");
        }
        try {
            IPage iPage = whsStorageInvSearchDTO.getPage();
            List<Map<String, Object>> mapList = this.baseMapper.getStorageInvList(iPage, whsStorageInvSearchDTO);
            return ResponseResult.success().add("whsStorageInventoryList", iPage.setRecords(mapList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksStorageInvList");
        }
    }

    /** 按工厂代码料号查询所有储位分布 */
    @Override
    public ResponseResult getWerksStorageByMaterialNo(String werks, String materialNo) {
        if (StringUtils.isEmpty(werks) || StringUtils.isEmpty(materialNo)){
            return ResponseResult.error("请求参数错误");
        }
        return ResponseResult.success().add("whsStorageInventory", this.baseMapper.getWhsStorageInventory(werks, materialNo));
    }
}
